package com.zhan.picturebackend.manager.sharding;

import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;

/**
 * 图片分表算法
 */
public class PictureShardingAlgorithm implements StandardShardingAlgorithm<Long> {

    /**
     *
     * @param availableTargetNames 已经支持分表的表名
     * @param preciseShardingValue spaceId(配置里写的 sharding-column: spaceId)
     * @return
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> preciseShardingValue) {
        Long spaceId = preciseShardingValue.getValue();
        String logicTableName = preciseShardingValue.getLogicTableName(); //获取逻辑表（picture）
        // spaceId 为 null 表示查询所有图片，所以直接返回逻辑表，挨个枚举查询所有的表
        if (spaceId == null) {
            return logicTableName;
        }
        // 根据 spaceId 动态生成分表名
        String realTableName = "picture_" + spaceId;
        // 如果该表名已经在支持分表的表名中，直接返回该表名，否则返回逻辑表名，挨个枚举查询所有的表
        // 但是 actual-data-nodes: picture.picture 配置的 availableTargetNames 始终为 picture，无法返回真实的分表
        // 所以需要自己写一个分表管理器 DynamicShardingManager，自己来维护分表列表，并更新到 ShardingSphere 的 actual-data-nodes 配置中
        if (availableTargetNames.contains(realTableName)) {
            return realTableName;
        } else {
            return logicTableName;
        }
    }

    // 该方法是对范围类的分片查询（rangeShardingValue），该项目没有根据多个spaceId查询的情况，所以不需要编写这个方法
    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {
        return new ArrayList<>();
    }

    @Override
    public Properties getProps() {
        return null;
    }

    @Override
    public void init(Properties properties) {

    }
}
